/**
	Pulsar engine. Additional include file.
	Memory manager (MSVC compatible).

	Copyright (C) 2013-2014 Dmitry Dolgov

	This program is free software; you can redistribute it and/or modify it under the terms of the
	GNU General Public License as published by the Free Software Foundation; either version 2 of
	the License, or (at your option) any later version.
		
	This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.
*/

#if !defined(__PL_NO_MEMORY_MAPPING__)

#define PL_DEFAULT_ALLOC_ALIGN 16

#if defined(PL_MEMORY_DEBUG)

inline void* __cdecl operator new (::size_t size, const pl_char* file, unsigned int line, const pl_char* func) throw(::std ::bad_alloc)
{
	void* p = pl::mallocDbg(size, pl::BLOCK_TYPE_NEW, PL_DEFAULT_ALLOC_ALIGN, file, line, func);
	if (p == NULL)
	{
		throw std::bad_alloc();
	}
	return p;
}

inline void* __cdecl operator new [] (::size_t size, const pl_char* file, unsigned int line, const pl_char* func) throw(::std ::bad_alloc)
{
	void* p = pl::mallocDbg(size, pl::BLOCK_TYPE_NEW_ARRAY, PL_DEFAULT_ALLOC_ALIGN, file, line, func);
	if (p == NULL)
	{
		throw std::bad_alloc();
	}
	return p;
}

inline void* __cdecl operator new (::size_t size, const ::std::nothrow_t &, const pl_char* file, unsigned int line, const pl_char* func) throw()
{
	return pl::mallocDbg(size, pl::BLOCK_TYPE_NEW, PL_DEFAULT_ALLOC_ALIGN, file, line, func);
}

inline void* __cdecl operator new [] (::size_t size, const ::std::nothrow_t &, const pl_char* file, unsigned int line, const pl_char* func) throw()
{
	return pl::mallocDbg(size, pl::BLOCK_TYPE_NEW_ARRAY, PL_DEFAULT_ALLOC_ALIGN, file, line, func);
}

inline void __cdecl operator delete (void* p, const pl_char* file, unsigned int line, const pl_char* func) throw (std::bad_alloc)
{
	if (p != NULL)
	{
		pl::freeDbg(p, pl::BLOCK_TYPE_NEW, file, line, func);
	}
	return;
}

inline void __cdecl operator delete [] (void* p, const pl_char* file, unsigned int line, const pl_char* func) throw (std::bad_alloc)
{
	if (p != NULL)
	{
		pl::freeDbg(p, pl::BLOCK_TYPE_NEW_ARRAY, file, line, func);
	}
	return;
}

#endif
#if defined(PL_MEMORY_DEBUG) || defined(PL_MEMORY_RELEASE) || defined(PL_MEMORY_FINAL)

inline void* __cdecl operator new (::size_t size, const ::std::nothrow_t &) throw()
{
#ifdef PL_MEMORY_DEBUG
	return pl::mallocDbg(size, pl::BLOCK_TYPE_NEW, PL_DEFAULT_ALLOC_ALIGN, NULL, 0, PL_T(""));
#else
	return malloc(size);
#endif
}

inline void* __cdecl operator new [] (::size_t size, const ::std::nothrow_t &) throw()
{
#ifdef PL_MEMORY_DEBUG
	return pl::mallocDbg(size, pl::BLOCK_TYPE_NEW_ARRAY, PL_DEFAULT_ALLOC_ALIGN, NULL, 0, PL_T(""));
#else
	return pl::mallocAlignRtl(PL_DEFAULT_ALLOC_ALIGN, size);
#endif
}

inline void* __cdecl operator new (::size_t size) throw(::std ::bad_alloc)
{
#ifdef PL_MEMORY_DEBUG
	return pl::mallocDbg(size, pl::BLOCK_TYPE_NEW, PL_DEFAULT_ALLOC_ALIGN, NULL, 0, PL_T(""));
#else
	return pl::mallocAlignRtl(PL_DEFAULT_ALLOC_ALIGN, size);
#endif
}

inline void* __cdecl operator new [] (::size_t size) throw(::std ::bad_alloc)
{
#ifdef PL_MEMORY_DEBUG
	return pl::mallocDbg(size, pl::BLOCK_TYPE_NEW_ARRAY, PL_DEFAULT_ALLOC_ALIGN, NULL, 0, PL_T(""));
#else
	return pl::mallocAlignRtl(PL_DEFAULT_ALLOC_ALIGN, size);
#endif
}

inline void __cdecl operator delete (void* p, const ::std::nothrow_t &) throw()
{
	if (p != NULL)
	{
#ifdef PL_MEMORY_DEBUG
		pl::freeDbg(p, pl::BLOCK_TYPE_NEW, NULL, 0, PL_T(""));
#else
		pl::freeAlignRtl(p);
#endif
	}
	return;
}

inline void __cdecl operator delete [] (void* p, const ::std::nothrow_t &) throw()
{
	if (p != NULL)
	{
#ifdef PL_MEMORY_DEBUG
		pl::freeDbg(p, pl::BLOCK_TYPE_NEW_ARRAY, NULL, 0, PL_T(""));
#else
		pl::freeAlignRtl(p);
#endif
	}
	return;
}

inline void __cdecl operator delete (void* p) throw()
{
	if (p != NULL)
	{
#ifdef PL_MEMORY_DEBUG
		pl::freeDbg(p, pl::BLOCK_TYPE_NEW, NULL, 0, PL_T(""));
#else
		pl::freeAlignRtl(p);
#endif
	}
	return;
}

inline void __cdecl operator delete [] (void* p) throw()
{
	if (p != NULL)
	{
#ifdef PL_MEMORY_DEBUG
		pl::freeDbg(p, pl::BLOCK_TYPE_NEW_ARRAY, NULL, 0, PL_T(""));
#else
		pl::freeAlignRtl(p);
#endif
	}
	return;
}

#elif defined(PL_MEMORY_NONE)

// Do nothing

#else
#error "Wrong memory manager settings"
#endif

#endif

//
// End of file 'pulsar_memory_msc.h'
//
